package tlstools

import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"fmt"
	"os"
)

var ErrConnNotEstablished = errors.New("尚未建立连接")

// TLSClient 是自定义的一个基于TCP协议的TLS客户端
type TLSClient struct {
	SocketAddr    string // SocketAddr 套接字地址
	connectStatus bool   // ConnectStatus client如果处于连接状态则为true，否则为false;使用getConnectStatus获取
	config        *tls.Config
	conn          *tls.Conn
}

func (c *TLSClient) ConnectStatus() bool {
	return c.connectStatus
}

func (c *TLSClient) Connect() error {
	dial, err := tls.Dial("tcp", c.SocketAddr, c.config)
	if err == nil {
		c.conn = dial
		c.connectStatus = true
	}
	return err
}

func (c *TLSClient) Stop() error {
	if c.connectStatus == false {
		return nil
	}
	if c.conn == nil {
		return nil
	}
	return c.conn.Close()
}

func NewTlsClient(ip string, port int, config *tls.Config) *TLSClient {
	tlsClient := &TLSClient{
		SocketAddr:    fmt.Sprintf("%s:%d", ip, port),
		connectStatus: false,
		config:        config,
	}
	return tlsClient
}

func (c *TLSClient) Write(data []byte) (int, error) {
	if !c.connectStatus {
		return 0, ErrConnNotEstablished
	}
	return c.conn.Write(data)
}

func (c *TLSClient) Read(buf []byte) (int, error) {
	if !c.connectStatus {
		return 0, ErrConnNotEstablished
	}
	return c.conn.Read(buf)
}

func AddCert(pool *x509.CertPool, certFileLocation string) error {
	cert, err := os.ReadFile(certFileLocation)
	if err != nil {
		return err
	}
	if ok := pool.AppendCertsFromPEM(cert); !ok {
		return errors.New(fmt.Sprintf("无法解析来自%s的文件", certFileLocation))
	}
	return nil
}
